﻿using System;
using System.Collections.Generic;
using System.Linq;

namespace ConsoleApp.enums
{
    /// <summary>
    /// 设备模型键
    /// </summary>
    public struct DeviceModelKey : IEquatable<DeviceModelKey>
    {
        public DeviceDomainEnums Domain { get; }
        public DeviceTypeEnums Type { get; }
        public DeviceSubTypeEnums SubType { get; }

        public DeviceModelKey(DeviceDomainEnums domain, DeviceTypeEnums type, DeviceSubTypeEnums subType)
        {
            Domain = domain;
            Type = type;
            SubType = subType;
        }

        public override string ToString()
        {
            return $"{(int)Domain}-{(int)Type}-{(int)SubType}";
        }

        public static DeviceModelKey Parse(string key)
        {
            if (string.IsNullOrEmpty(key))
                throw new ArgumentException("Key cannot be null or empty", nameof(key));

            var parts = key.Split('-');
            if (parts.Length != 3)
                throw new FormatException("Key must be in format 'domain-type-subType'");

            if (!int.TryParse(parts[0], out int domain) ||
                !int.TryParse(parts[1], out int type) ||
                !int.TryParse(parts[2], out int subType))
                throw new FormatException("All parts must be integers");

            return new DeviceModelKey(
                (DeviceDomainEnums)domain,
                (DeviceTypeEnums)type,
                (DeviceSubTypeEnums)subType);
        }

        public bool Equals(DeviceModelKey other)
        {
            return Domain == other.Domain && Type == other.Type && SubType == other.SubType;
        }

        public override bool Equals(object obj)
        {
            return obj is DeviceModelKey other && Equals(other);
        }


        public static bool operator ==(DeviceModelKey left, DeviceModelKey right)
        {
            return left.Equals(right);
        }

        public static bool operator !=(DeviceModelKey left, DeviceModelKey right)
        {
            return !left.Equals(right);
        }
    }

    /// <summary>
    /// 设备模型
    /// </summary>
    public static class DeviceModels
    {
        public static readonly DeviceModelKey M400 = new DeviceModelKey(
            DeviceDomainEnums.Drone, DeviceTypeEnums.M400, DeviceSubTypeEnums.ZERO);

        public static readonly DeviceModelKey M350 = new DeviceModelKey(
            DeviceDomainEnums.Drone, DeviceTypeEnums.M350, DeviceSubTypeEnums.ZERO);

        public static readonly DeviceModelKey M300 = new DeviceModelKey(
            DeviceDomainEnums.Drone, DeviceTypeEnums.M300, DeviceSubTypeEnums.ZERO);

        public static readonly DeviceModelKey M30 = new DeviceModelKey(
            DeviceDomainEnums.Drone, DeviceTypeEnums.M30, DeviceSubTypeEnums.ZERO);

        public static readonly DeviceModelKey M30T = new DeviceModelKey(
            DeviceDomainEnums.Drone, DeviceTypeEnums.M30T, DeviceSubTypeEnums.ONE);

        public static readonly DeviceModelKey M3TD = new DeviceModelKey(
            DeviceDomainEnums.Drone, DeviceTypeEnums.M3TD, DeviceSubTypeEnums.ONE);

        public static readonly DeviceModelKey M4TD = new DeviceModelKey(
            DeviceDomainEnums.Drone, DeviceTypeEnums.M4TD, DeviceSubTypeEnums.ONE);

        public static readonly DeviceModelKey H20 = new DeviceModelKey(
            DeviceDomainEnums.Drone, DeviceTypeEnums.M4TD, DeviceSubTypeEnums.ONE);

        private static readonly Dictionary<string, DeviceModelKey> KnownDevices = new Dictionary<string, DeviceModelKey>
        {
            ["M400"] = M400,
            ["M350"] = M350,
            ["M300"] = M300,
            ["M30T"] = M30T,
            ["M3TD"] = M3TD,
            ["M4TD"] = M4TD,
        };

        public static DeviceModelKey? FromName(string name)
        {
            return KnownDevices.TryGetValue(name, out var key) ? key : (DeviceModelKey?)null;
        }

        public static string GetName(DeviceModelKey key)
        {
            return KnownDevices.FirstOrDefault(x => x.Value.Equals(key)).Key;
        }
    }

    public struct PayloadDeviceModelKey : IEquatable<PayloadDeviceModelKey>
    {
        public DeviceTypeEnums Type { get; }
        public DeviceSubTypeEnums SubType { get; }
        // Gimbalindex: 左舷侧（主云台） 0, 右舷侧 1, 上侧 2
        public int Gimbalindex { get; }

        public PayloadDeviceModelKey(DeviceTypeEnums type, DeviceSubTypeEnums subType, int gimbalindex)
        {
            Type = type;
            SubType = subType;
            Gimbalindex = gimbalindex;
        }

        public override string ToString()
        {
            return $"{(int)Type}-{(int)SubType}-{Gimbalindex}";
        }

        public static PayloadDeviceModelKey Parse(string key)
        {
            if (string.IsNullOrEmpty(key))
                throw new ArgumentException("Key cannot be null or empty", nameof(key));

            var parts = key.Split('-');
            if (parts.Length != 3)
                throw new FormatException("Key must be in format 'domain-type-subType'");

            if (!int.TryParse(parts[0], out int type) ||
                !int.TryParse(parts[1], out int subType) ||
                !int.TryParse(parts[2], out int gimbalindex))
                throw new FormatException("All parts must be integers");

            return new PayloadDeviceModelKey(
                (DeviceTypeEnums)type,
                (DeviceSubTypeEnums)subType, gimbalindex);
        }

        public bool Equals(PayloadDeviceModelKey other)
        {
            return Type == other.Type && SubType == other.SubType && Gimbalindex == other.Gimbalindex;
        }

        public override bool Equals(object obj)
        {
            return obj is PayloadDeviceModelKey other && Equals(other);
        }


        public static bool operator ==(PayloadDeviceModelKey left, PayloadDeviceModelKey right)
        {
            return left.Equals(right);
        }

        public static bool operator !=(PayloadDeviceModelKey left, PayloadDeviceModelKey right)
        {
            return !left.Equals(right);
        }
    }

    /// <summary>
    /// 设备模型
    /// </summary>
    public static class PayloadDeviceModels
    {
        // Gimbalindex: 左舷侧（主云台） 0, 右舷侧 1, 上侧 2
        public static readonly PayloadDeviceModelKey Z30 = new PayloadDeviceModelKey(
            DeviceTypeEnums.Z30, DeviceSubTypeEnums.ZERO, 0);

        public static readonly PayloadDeviceModelKey XT2 = new PayloadDeviceModelKey (
            DeviceTypeEnums.XT2, DeviceSubTypeEnums.ZERO, 0);

        public static readonly PayloadDeviceModelKey XTS = new PayloadDeviceModelKey(
                   DeviceTypeEnums.XTS, DeviceSubTypeEnums.ZERO, 0);

        public static readonly PayloadDeviceModelKey H20 = new PayloadDeviceModelKey(
                   DeviceTypeEnums.H20, DeviceSubTypeEnums.ZERO, 0);

        public static readonly PayloadDeviceModelKey H20T = new PayloadDeviceModelKey(
                   DeviceTypeEnums.H20T, DeviceSubTypeEnums.ZERO, 0);

        public static readonly PayloadDeviceModelKey H30 = new PayloadDeviceModelKey(
                   DeviceTypeEnums.H30, DeviceSubTypeEnums.ZERO, 0);

        public static readonly PayloadDeviceModelKey H30T = new PayloadDeviceModelKey(
                   DeviceTypeEnums.H30T, DeviceSubTypeEnums.ZERO, 0);

        public static readonly PayloadDeviceModelKey M30 = new PayloadDeviceModelKey(
                   DeviceTypeEnums.M30_CAMERA, DeviceSubTypeEnums.ZERO, 0);

        public static readonly PayloadDeviceModelKey M30T = new PayloadDeviceModelKey(
                   DeviceTypeEnums.M30T_CAMERA, DeviceSubTypeEnums.ZERO, 0);

        public static readonly PayloadDeviceModelKey M3D = new PayloadDeviceModelKey(
                   DeviceTypeEnums.M3D_CAMERA, DeviceSubTypeEnums.ZERO, 0);

        public static readonly PayloadDeviceModelKey M3TD = new PayloadDeviceModelKey(
                   DeviceTypeEnums.M3TD_CAMERA, DeviceSubTypeEnums.ZERO, 0);

        public static readonly PayloadDeviceModelKey M4D = new PayloadDeviceModelKey(
                   DeviceTypeEnums.M4D_CAMERA, DeviceSubTypeEnums.ZERO, 0);

        public static readonly PayloadDeviceModelKey M4TD = new PayloadDeviceModelKey(
                   DeviceTypeEnums.M4TD_CAMERA, DeviceSubTypeEnums.ZERO, 0);

        private static readonly Dictionary<string, PayloadDeviceModelKey> KnownDevices = new Dictionary<string, PayloadDeviceModelKey>
        {
            ["H20T"] = H20T,
            ["H30T"] = H30T,
            ["M30T"] = M30T,
            ["M3TD"] = M3TD,
            ["M4TD"] = M4TD,
        };

        public static PayloadDeviceModelKey? FromName(string name)
        {
            return KnownDevices.TryGetValue(name, out var key) ? key : (PayloadDeviceModelKey?)null;
        }

        public static string GetName(PayloadDeviceModelKey key)
        {
            return KnownDevices.FirstOrDefault(x => x.Value.Equals(key)).Key;
        }
    }

}
